<template>
  <div class="app-container spa-appointment">
    <div
      v-loading="loading"
      class="bg-white rounded-lg shadow-sm calendar-container"
    >
      <FullCalendar ref="calendarRef" :options="calendarOptions" />
    </div>

    <!-- 自定义 Popover -->
    <div
      v-if="popoverVisible"
      class="custom-popover"
      :style="{
        left: popoverPosition.x + 'px',
        top: popoverPosition.y + 'px'
      }"
      @mouseenter="handlePopoverMouseEnter"
      @mouseleave="handlePopoverMouseLeave"
    >
      <div v-if="currentEventData" class="popover-content">
        <!-- Header -->
        <div class="popover-header">
          <div v-if="currentEventData.data_type === 1">
            <div class="customer-info">
              <span class="customer-name"
                >{{ currentEventData.customerName }}（{{
                  currentEventData.l_no
                }}）</span
              >
              <span class="customer-mobile">{{
                currentEventData.customerMobileVal
              }}</span>
            </div>

            <span
              class="status-badge"
              :class="`status-${currentEventData.status}`"
            >
              {{ getStatusText(currentEventData.status) }}
            </span>
            <span
              class="status-badge ml-2"
              :class="`status-${currentEventData.l_pay_status}`"
            >
              {{ currentEventData.pay_status }}
            </span>
            <span
              v-if="currentEventData.l_type"
              class="status-badge ml-2 status-1"
            >
              {{
                clockTypeList.find(item => item.id === currentEventData.l_type)
                  ?.name
              }}
            </span>
            <span class="ml-2">
              <el-button
                v-if="currentEventData.status === '2'"
                size="small"
                type="primary"
                @click="handleStartClock"
              >
                开始上钟
              </el-button>
              <el-button
                v-if="currentEventData.status === '2'"
                size="small"
                type="success"
                @click="handleConfirmClock"
              >
                确认已上钟
              </el-button>
            </span>
          </div>
          <div v-else class="font-bold">占用详情</div>
        </div>

        <!-- Body -->
        <div class="popover-body">
          <div class="info-grid">
            <div class="info-item">
              <i class="icon-time" />
              <span
                >{{ currentEventData.startTimeStr }} ~
                {{ currentEventData.endTimeStr }}</span
              >
            </div>
            <div class="info-item">
              <i class="icon-user" />
              <span>{{ currentEventData.technicianName }}</span>
            </div>
            <div v-if="currentEventData.data_type === 1" class="info-item">
              <i class="icon-service" />
              <span>{{ currentEventData.projectName }}</span>
            </div>
            <div v-if="currentEventData.data_type === 1" class="info-item">
              <i class="icon-price" />
              <span>¥{{ currentEventData.price }}</span>
            </div>
            <div v-if="currentEventData.data_type === 2" class="info-item">
              <i class="icon-duration" />
              <span>{{ currentEventData.date_long }}</span>
            </div>
            <div v-if="currentEventData.remark" class="info-item full-width">
              <i class="icon-note" />
              <span>{{ currentEventData.remark }}</span>
            </div>
          </div>
        </div>

        <!-- Footer Actions -->
        <div class="popover-footer">
          <el-button
            v-if="['1', '3'].includes(currentEventData.status)"
            size="small"
            type="success"
            @click="handleConfirmArrival"
          >
            确认到店
          </el-button>
          <el-button
            v-if="
              currentEventData.data_type === 1 &&
              currentEventData.l_pay_status === '1' &&
              ['2', '5'].includes(currentEventData.status)
            "
            size="small"
            type="warning"
            @click="handleConfirmPayment"
          >
            确认支付
          </el-button>
          <el-button
            v-if="currentEventData.data_type === 2"
            size="small"
            type="danger"
            @click="handleCancelOccupation"
          >
            取消占用
          </el-button>
          <!--          v-if="['1', '2'].includes(currentEventData.status)"-->
          <el-button
            v-if="isCancelBtn(currentEventData.l_yytime)"
            size="small"
            type="danger"
            @click="handleCancelOrder"
          >
            取消预约
          </el-button>
          <el-button
            v-if="currentEventData.data_type === 2"
            size="small"
            type="primary"
            @click="handleEditOccupation"
          >
            编辑占用
          </el-button>
          <el-button
            v-if="currentEventData.data_type === 1"
            size="small"
            type="primary"
            @click="handleEditAppointment"
          >
            编辑预约
          </el-button>
        </div>
      </div>
    </div>

    <el-dialog
      v-model="dialogVisible"
      :close-on-click-modal="false"
      :title="title"
      width="600px"
    >
      <el-tabs v-model="activeTab" class="mb-4">
        <el-tab-pane :label="title" name="appointment">
          <el-form
            ref="formRef"
            :model="form"
            :rules="rules"
            label-width="110px"
            class="p-4"
          >
            <!-- 客户信息 -->
            <div class="mb-4">
              <h4 class="mb-2 font-medium text-gray-700">客户信息</h4>
            </div>

            <el-form-item label="选择会员" prop="selectedMember">
              <el-select
                v-model="selectedMemberId"
                placeholder="请选择会员"
                :disabled="eventClickFlag"
                style="width: 100%"
                filterable
                remote
                :remote-method="searchMembers"
                :loading="memberSearchLoading"
                @change="onMemberChange"
              >
                <el-option
                  v-for="member in filteredMemberList"
                  :key="member.m_id"
                  :label="`${member.m_name} (${member.mobile_val})`"
                  :value="member.m_id"
                />
              </el-select>
            </el-form-item>

            <el-form-item label="客户姓名" prop="name">
              <el-input
                v-model="form.name"
                placeholder="请输入客户姓名"
                :disabled="eventClickFlag"
                @input="onNameChange"
              />
            </el-form-item>

            <el-form-item label="联系电话" prop="mobile">
              <el-input
                v-model="form.mobile_val"
                placeholder="请输入联系电话"
                :disabled="eventClickFlag"
                @input="onMobileChange"
              />
            </el-form-item>

            <!-- 预约信息 -->
            <div class="mt-6 mb-4">
              <h4 class="mb-2 font-medium text-gray-700">预约信息</h4>
            </div>

            <el-form-item label="服务项目" prop="pid">
              <el-select
                v-model="form.pid"
                placeholder="请选择服务项目"
                :disabled="eventClickFlag"
                style="width: 100%"
                @change="projectChange"
              >
                <el-option
                  v-for="project in projectList"
                  :key="project.p_id"
                  :label="`${project.p_name} (¥${project.p_price})`"
                  :value="project.p_id"
                />
              </el-select>
            </el-form-item>

            <el-form-item label="预约日期" prop="selectedDate">
              <el-select
                v-model="selectedAppointmentDate"
                placeholder="请选择预约日期"
                :disabled="eventClickFlag"
                style="width: 100%"
                @change="onAppointmentDateChange"
              >
                <el-option
                  v-for="dateItem in appointmentDates"
                  :key="dateItem.date"
                  :label="`${formatDateDisplay(dateItem.date)} ${dateItem.dayOfWeekStr}`"
                  :value="dateItem.date"
                />
              </el-select>
            </el-form-item>

            <el-form-item label="预约时间" prop="selectedTime">
              <el-select
                v-model="selectedAppointmentTime"
                placeholder="请选择预约时间"
                :disabled="eventClickFlag || !selectedAppointmentDate"
                style="width: 100%"
                @change="onAppointmentTimeChange"
              >
                <el-option
                  v-for="timeSlot in appointmentTimeSlots"
                  :key="timeSlot.startDate"
                  :label="formatTimeDisplay(timeSlot.startDate)"
                  :value="timeSlot.startDate"
                  :disabled="!timeSlot.canMakeAppointment"
                />
              </el-select>
            </el-form-item>

            <el-form-item label="技师" prop="tid">
              <el-select
                v-model="form.tid"
                placeholder="请选择技师"
                :disabled="eventClickFlag"
                style="width: 100%"
                @change="employeeChange"
              >
                <el-option
                  v-for="employee in employeeList"
                  :key="employee.t_id"
                  :label="employee.t_name"
                  :value="employee.t_id"
                />
              </el-select>
            </el-form-item>

            <el-form-item label="上钟类型" prop="type">
              <el-select
                v-model="form.type"
                placeholder="请选择上钟类型"
                :disabled="eventClickFlag || !form.tid"
                style="width: 100%"
              >
                <el-option
                  v-for="clockType in clockTypeList"
                  :key="clockType.id"
                  :label="clockType.name"
                  :value="clockType.id"
                />
              </el-select>
            </el-form-item>

            <el-form-item label="备注" prop="remark">
              <el-input
                v-model="form.remark"
                type="textarea"
                placeholder="请输入备注信息"
                :disabled="eventClickFlag"
              />
            </el-form-item>
          </el-form>
        </el-tab-pane>

        <el-tab-pane
          v-if="(!eventClickFlag && !isEditMode) || isEditOccupationMode"
          :label="isEditOccupationMode ? '编辑占用' : '临时占用'"
          name="occupation"
        >
          <el-form
            ref="occupationFormRef"
            :model="occupationForm"
            :rules="occupationRules"
            label-width="110px"
            class="p-4"
          >
            <el-form-item label="员工" prop="tid">
              <el-select
                v-model="occupationForm.tid"
                placeholder="请选择员工"
                style="width: 100%"
              >
                <el-option
                  v-for="employee in employeeList"
                  :key="employee.t_id"
                  :label="employee.t_name"
                  :value="employee.t_id"
                />
              </el-select>
            </el-form-item>

            <el-form-item label="占用时间" prop="date">
              <el-date-picker
                v-model="occupationForm.date"
                type="date"
                value-format="YYYY-MM-DD"
                placeholder="请选择占用日期"
                style="width: 100%"
              />
            </el-form-item>

            <el-form-item label="开始时间" prop="startTime">
              <el-time-picker
                v-model="occupationForm.startTime"
                value-format="HH:mm"
                placeholder="请选择开始时间"
                style="width: 100%"
              />
            </el-form-item>

            <el-form-item label="结束时间" prop="endTime">
              <el-time-picker
                v-model="occupationForm.endTime"
                value-format="HH:mm"
                placeholder="请选择结束时间"
                style="width: 100%"
              />
            </el-form-item>

            <el-form-item label="备注" prop="remark">
              <el-input
                v-model="occupationForm.remark"
                type="textarea"
                placeholder="请输入占用原因（必填）"
                maxlength="50"
                show-word-limit
              />
            </el-form-item>
          </el-form>
        </el-tab-pane>
      </el-tabs>
      <template #footer>
        <div class="flex justify-end gap-3">
          <el-button @click="dialogVisible = false">取 消</el-button>
          <el-button
            v-if="!eventClickFlag && activeTab === 'appointment'"
            type="primary"
            :loading="buttonLoading"
            @click="submitForm"
          >
            确 定
          </el-button>
          <el-button
            v-if="activeTab === 'occupation'"
            type="primary"
            :loading="occupationButtonLoading"
            @click="submitOccupationForm"
          >
            {{ isEditOccupationMode ? "保存修改" : "确 定" }}
          </el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>
<script setup lang="ts">
import {
  ref,
  reactive,
  onMounted,
  nextTick,
  onUnmounted,
  unref,
  computed
} from "vue";
import { ElMessage, ElMessageBox } from "element-plus";
import Plus from "~icons/ep/plus";
// 导入FullCalendar组件和插件
import FullCalendar from "@fullcalendar/vue3";
import { Calendar } from "@fullcalendar/core";
import dayGridPlugin from "@fullcalendar/daygrid";
import interactionPlugin from "@fullcalendar/interaction";
import timeGridPlugin from "@fullcalendar/timegrid";
import resourceTimelinePlugin from "@fullcalendar/resource-timeline";
import resourceTimeGridPlugin from "@fullcalendar/resource-timegrid";
import { ElLoading } from "element-plus";

// 导入API服务
import {
  getEmployeeList,
  addOccupation,
  editOccupation,
  cancelOccupation,
  getDutyPerson,
  type Employee,
  type AddOccupationParams,
  type EditOccupationParams
} from "@/api/employee";
import {
  orderAction,
  getOrderList,
  getAppointmentDates,
  getAppointmentEmployees,
  getTimeSlots,
  cancelOrder,
  confirmArrival,
  confirmPayment,
  getClockTypes,
  startClock,
  confirmClock,
  type Order,
  type OrderActionParams,
  type OrderListParams,
  type AppointmentDate,
  type AppointmentEmployee,
  type TimeSlot,
  type ClockType
} from "@/api/order";
import { getProjectList, type Project } from "@/api/project";
import {
  getMemberList,
  type Member,
  type MemberSearchParams
} from "@/api/member";

defineOptions({
  name: "AppointmentManagement"
});

// SPA预约表单数据类型
interface FormData {
  id?: number; // 预约id（编辑时使用）
  mid?: number; // 会员id
  name: string; // 客户姓名
  mobile: string; // 客户电话
  date: string; // 预约时间
  tid: string; // 技师id
  type: string; // 上钟类型
  pid: string; // 项目id
  remark: string; // 备注
  mobile_val: string; // 手机号码展示值
}

// 临时占用表单数据类型
interface OccupationFormData {
  id?: number; // 占用id（编辑时使用）
  tid: string; // 员工id
  date: string; // 占用日期
  startTime: string; // 开始时间
  endTime: string; // 结束时间
  remark: string; // 备注
}

// 响应式数据
const loading = ref(false);
const buttonLoading = ref(false);
const occupationButtonLoading = ref(false);
const dialogVisible = ref(false);
const eventClickFlag = ref(false);
const isEditMode = ref(false); // 新增：区分编辑模式
const isEditOccupationMode = ref(false); // 新增：区分编辑占用模式
const title = ref("");
const calendarRef = ref();
const formRef = ref();
const occupationFormRef = ref();
const activeTab = ref("appointment");
const dutyPerson = ref("");
const dutyPersonTimer = ref<NodeJS.Timeout | null>(null);

// Popover 相关
const popoverVisible = ref(false);
const popoverContent = ref<any>(null);
const popoverPosition = reactive({ x: 0, y: 0 });
const popoverTimer = ref<NodeJS.Timeout | null>(null);
const currentEventData = ref<any>(null);

// 数据列表
const employeeList = ref<Employee[]>([]);
const projectList = ref<Project[]>([]);
const orderList = ref<Order[]>([]);
const memberList = ref<Member[]>([]);
const clockTypeList = ref<ClockType[]>([]);

// 预约时间选择相关
const appointmentDates = ref<AppointmentDate[]>([]);
const appointmentTimeSlots = ref<TimeSlot[]>([]);
const selectedAppointmentDate = ref("");
const selectedAppointmentTime = ref("");

// 会员搜索相关
const memberSearchKeyword = ref("");
const filteredMemberList = ref<Member[]>([]);
const memberSearchLoading = ref(false);

// 表单数据
const form = reactive<FormData>({
  name: "",
  mobile: "",
  date: "",
  tid: "",
  type: "",
  pid: "",
  remark: "",
  mobile_val: "" // 手机号码展示值
});

// 选中的会员ID
const selectedMemberId = ref("");

// 临时占用表单数据
const occupationForm = reactive<OccupationFormData>({
  id: undefined,
  tid: "",
  date: "",
  startTime: "",
  endTime: "",
  remark: ""
});

// 表单验证规则
const rules = reactive({
  name: [{ required: true, message: "请输入客户姓名", trigger: "blur" }],
  mobile: [{ required: true, message: "请输入联系电话", trigger: "blur" }],
  pid: [{ required: true, message: "请选择服务项目", trigger: "change" }],
  type: [
    {
      validator: (rule: any, value: string, callback: any) => {
        if (form.tid && !value) {
          callback(new Error("选择技师时，上钟类型必填"));
        } else {
          callback();
        }
      },
      trigger: "change"
    }
  ]
});

// 临时占用表单验证规则
const occupationRules = reactive({
  tid: [{ required: true, message: "请选择员工", trigger: "change" }],
  date: [{ required: true, message: "请选择占用日期", trigger: "change" }],
  startTime: [{ required: true, message: "请选择开始时间", trigger: "change" }],
  endTime: [
    { required: true, message: "请选择结束时间", trigger: "change" },
    {
      validator: (rule: any, value: string, callback: any) => {
        if (
          value &&
          occupationForm.startTime &&
          value <= occupationForm.startTime
        ) {
          callback(new Error("结束时间必须大于开始时间"));
        } else {
          callback();
        }
      },
      trigger: "change"
    }
  ],
  remark: [
    { required: true, message: "请输入占用原因", trigger: "blur" },
    { min: 1, max: 50, message: "备注长度在 1 到 50 个字符", trigger: "blur" }
  ]
});

// 查询参数
const queryParams = reactive<OrderListParams>({
  start_date: null,
  end_date: null,
  keys: "",
  status: "",
  // page: 1,
  // isindex在接口增加一下这个参数，为1的时候我就知道是从首页请求的数据，这个时候我不加限制，数据全量吐出
  isindex: 1,
  num: 100,
  zhanyong: true
});

// 日历实例和配置
const calendar = ref<Calendar | null>(null);
const viewType = ref("");

// FullCalendar配置
const calendarOptions = reactive({
  dutyPerson: dutyPerson.value,
  height: 900,
  allDaySlot: false,
  axisFormat: "h(:mm)tt",
  plugins: [
    dayGridPlugin,
    interactionPlugin,
    timeGridPlugin,
    resourceTimelinePlugin,
    resourceTimeGridPlugin
  ],
  headerToolbar: {
    left: "addAppointment,refresh",
    center: "title",
    right: "prev,next,today,resourceTimeGridDay,dayGridMonth"
  },
  buttonText: {
    today: "今天",
    day: "日",
    week: "周",
    month: "月"
  },
  editable: true,
  selectable: true,
  navLinks: true,
  datesSet: datesSet,
  initialView: "resourceTimeGridDay",
  dateClick: handleDateClick,
  eventClick: handleEventClick,
  select: handleSelect,
  selectAllow: (selectInfo: any) => {
    const now = new Date();
    const selectedStart = new Date(selectInfo.start);
    return selectedStart.getTime() > now.getTime();
  },

  eventColor: "#fe6976",
  locale: "zh-cn",
  weekNumberCalculation: "ISO",
  customButtons: {
    addAppointment: {
      text: "新增预约",
      click: () => {
        openDialog();
      }
    },
    refresh: {
      text: "刷新",
      click: () => {
        refreshCalendar();
      }
    },
    prev: {
      text: "PREV",
      click: () => {
        prev();
      }
    },
    next: {
      text: "NEXT",
      click: () => {
        next();
      }
    },
    today: {
      text: "今天",
      click: () => {
        today();
      }
    }
  },
  slotMinTime: "12:00:00",
  slotMaxTime: "26:00:00",

  schedulerLicenseKey: "CC-Attribution-NonCommercial-NoDerivatives",
  events: [] as any[],
  eventDidMount: function (info: any) {
    // 添加自定义悬停效果
    const extendedProps = info.event.extendedProps;
    if (extendedProps) {
      info.el.style.cursor = "pointer";

      // 添加悬停事件
      info.el.addEventListener("mouseenter", (e: MouseEvent) => {
        showPopover(e, extendedProps);
      });

      info.el.addEventListener("mouseleave", () => {
        hidePopoverWithDelay();
      });
    }
  }
});

// 方法定义
/** 初始化数据 */
async function initData() {
  await loadEmployees();
  await loadProjects();
  await loadAppointmentDates();
  await loadMembers();
  await loadClockTypes();
  await loadOrders();
  await loadDutyPerson();
}

/**
 * 获取陪班人员名字 @getDutyPerson
 */
async function loadDutyPerson() {
  try {
    const res = await getDutyPerson();
    dutyPerson.value = res.data.name;
    // 清除之前可能存在的自定义文字
    let existingSpan = document.querySelector(".custom-duty-text");
    if (existingSpan) {
      existingSpan.remove();
    }
    // 添加新的自定义文字
    let toolbar = document.querySelector(".fc-toolbar-title");
    if (toolbar) {
      let customSpan = document.createElement("span");
      customSpan.innerHTML = "陪班人员：" + dutyPerson.value;
      customSpan.style.marginLeft = "15px";
      customSpan.style.fontSize = "14px";
      customSpan.className = "custom-duty-text";
      toolbar.appendChild(customSpan);
    }
  } catch (error) {
    console.error("获取陪班人员名字:", error);
    ElMessage.error("获取陪班人员名字");
  }
}

/** 加载员工列表 */
async function loadEmployees() {
  try {
    const response = await getEmployeeList({ status: "1" }); // 只获取在职员工
    if (response.code === 1) {
      employeeList.value = response.data.list.filter(
        (item: any) => item.t_type === "1"
      );
    } else {
      ElMessage.error(response.msg || "获取员工列表失败");
    }
  } catch (error) {
    console.error("获取员工列表失败:", error);
    ElMessage.error("获取员工列表失败");
  }
}

/** 加载项目列表 */
async function loadProjects() {
  try {
    const response = await getProjectList({ status: "1" }); // 只获取上架项目
    if (response.code === 1) {
      projectList.value = response.data;
    } else {
      ElMessage.error(response.msg || "获取项目列表失败");
    }
  } catch (error) {
    console.error("获取项目列表失败:", error);
    ElMessage.error("获取项目列表失败");
  }
}

/** 加载预约日期列表 */
async function loadAppointmentDates() {
  try {
    const response = await getAppointmentDates();
    if (response.code === 1) {
      appointmentDates.value = response.data;
    } else {
      ElMessage.error(response.msg || "获取预约日期失败");
    }
  } catch (error) {
    console.error("获取预约日期失败:", error);
    ElMessage.error("获取预约日期失败");
  }
}

/** 加载会员列表 */
async function loadMembers() {
  try {
    const response = await getMemberList({ num: "100", page: "1" });
    if (response.code === 1) {
      memberList.value = response.data.list;
      filteredMemberList.value = response.data.list;
    } else {
      ElMessage.error(response.msg || "获取会员列表失败");
    }
  } catch (error) {
    console.error("获取会员列表失败:", error);
    ElMessage.error("获取会员列表失败");
  }
}

/** 加载上钟类型列表 */
async function loadClockTypes() {
  try {
    const response = await getClockTypes();
    if (response.code === 1) {
      // 处理API返回数据，可能是键值对格式或数组格式
      if (Array.isArray(response.data)) {
        clockTypeList.value = response.data;
      } else {
        // 将键值对格式转换为数组格式
        clockTypeList.value = Object.entries(response.data).map(
          ([id, name]) => ({
            id,
            name
          })
        );
      }
    } else {
      ElMessage.error(response.msg || "获取上钟类型列表失败");
    }
  } catch (error) {
    console.error("获取上钟类型列表失败:", error);
    ElMessage.error("获取上钟类型列表失败");
  }
}

/** 获取当前的年月日，做查询参数 */
function setCurrentDate(data: Date): string {
  const currentDate = data;
  const year = currentDate.getFullYear();
  const month = String(currentDate.getMonth() + 1).padStart(2, "0");
  const day = String(currentDate.getDate()).padStart(2, "0");
  const formattedDate = `${year}-${month}-${day}`;
  return formattedDate;
}

/** 加载预约订单列表 */
async function loadOrders() {
  try {
    loading.value = true;
    await nextTick();
    // 如果日历已初始化，使用当前视图的日期范围，否则使用当天
    if (calendar.value) {
      getViewDate();
    } else {
      // 设置查询时间范围（当前日期）
      const today = new Date();
      const startDate = setCurrentDate(today) + " 00:00:00";
      const endDate = setCurrentDate(today) + " 23:59:59";

      queryParams.start_date = startDate;
      queryParams.end_date = endDate;
    }

    const response = await getOrderList(queryParams);
    if (response.code === 1) {
      const list = response.data?.list || [];
      orderList.value = list.filter(item => item.l_ystatus !== "4");
      await updateCalendarData();
    } else {
      ElMessage.error(response.msg || "获取预约列表失败");
    }
  } catch (error) {
    console.error("获取预约列表失败:", error);
    ElMessage.error("获取预约列表失败");
  } finally {
    loading.value = false;
  }
}

/** 更新日历数据 */
async function updateCalendarData() {
  await nextTick(() => {
    if (!calendar.value) return;

    // 清空所有事件
    calendar.value.removeAllEvents();

    // 清空原有资源
    const resourceIds = calendar.value
      .getResources()
      .map(resource => resource.id);
    resourceIds.forEach(id => {
      calendar.value?.getResourceById(id)?.remove();
    });

    // 添加员工作为资源
    if (employeeList.value.length > 0) {
      if (orderList.value.length > 0) {
        const isl_jmid = orderList.value.some(item => item.l_jmid == 0);
        const isl_tid = orderList.value.some(item => item.l_tid == 0);
        if (isl_tid || isl_jmid) {
          calendar.value?.addResource({
            id: "0",
            title: "未分配"
          });
        }
      }

      employeeList.value.forEach(employee => {
        calendar.value?.addResource({
          id: employee.t_id,
          title: employee.t_name
        });
      });
      console.log("员工列表:", employeeList.value);
    }

    // 添加预约事件
    if (orderList.value.length > 0) {
      orderList.value.forEach(order => {
        // 计算结束时间（开始时间 + 项目时长）
        const startTime = order.yydate
          ? new Date(order.yydate)
          : new Date(order.l_stime * 1000);
        const endTime = order.l_totaltime
          ? new Date(startTime.getTime() + parseInt(order.l_totaltime) * 1000)
          : new Date(order.l_etime * 1000);

        // 格式化时间显示
        const startTimeStr = startTime.toLocaleTimeString("zh-CN", {
          hour: "2-digit",
          minute: "2-digit"
        });
        const endTimeStr = endTime.toLocaleTimeString("zh-CN", {
          hour: "2-digit",
          minute: "2-digit"
        });

        const resourceId = order.l_jmid ? order.l_jmid : order.l_tid;
        const startTimedata = order.yydate
          ? order.yydate
          : new Date(order.l_stime * 1000);
        const titleHtml = order.l_mname
          ? `姓名:${order.l_mname}  状态:${order.mstatus}\nMID:${order.l_mid}\n手机号: ${order.mobile_val}\n${order.l_pname}`
          : `${order.date_time}\n临时占用`;
        calendar.value?.addEvent({
          resourceId: resourceId,
          title: titleHtml,
          start: startTimedata,
          end: endTime.toISOString(),
          extendedProps: {
            data_type: order.data_type,
            date_long: order.date_long,
            l_no: order.l_no,
            l_type: order.l_type,
            orderId: order.l_id,
            l_yytime: order.l_yytime,
            customerName: order.l_mname,
            customerMobile: order.l_mobile,
            customerMobileVal: order.mobile_val,
            projectName: order.l_pname,
            technicianId: order.l_jmid,
            technicianName: order.jname,
            status: order.l_ystatus,
            remark: order.l_remark,
            price: order.l_prices,
            pay_status: order.pay_status,
            l_pay_status: order.l_pay_status,
            startTimeStr: startTimeStr,
            endTimeStr: endTimeStr
          },
          // 添加悬停提示
          display: "block",
          backgroundColor: getStatusColor(order.l_ystatus),
          borderColor: getStatusColor(order.l_ystatus)
        });
      });
    }
  });
}

/** 初始化日历 */
function initCalendar() {
  const calendarEl =
    calendarRef.value?.$el || document.querySelector(".calendar-container .fc");
  if (calendarEl) {
    calendar.value = new Calendar(calendarEl, calendarOptions);
    calendar.value.render();
  }
}

/** 打开对话框 */
function openDialog() {
  resetForm();
  resetOccupationForm();
  title.value = "新增预约";
  eventClickFlag.value = false;
  isEditMode.value = false; // 重置编辑模式
  isEditOccupationMode.value = false; // 重置编辑占用模式
  activeTab.value = "appointment";
  dialogVisible.value = true;
}

/** 项目选择变化 */
function projectChange(value: string) {
  const selectedProject = projectList.value.find(
    project => project.p_id === value
  );
  if (selectedProject) {
    console.log("选择的项目:", selectedProject);
  }
}

/** 员工选择变化 */
function employeeChange(value: string) {
  const selectedEmployee = employeeList.value.find(
    employee => employee.t_id === value
  );
  if (selectedEmployee) {
    console.log("选择的员工:", selectedEmployee);
  } else {
    // 如果取消选择员工，清空上钟类型
    form.type = "";
  }

  // 重新验证上钟类型字段
  nextTick(() => {
    if (formRef.value) {
      formRef.value.validateField("type");
    }
  });
}

/** 预约日期选择变化 */
async function onAppointmentDateChange(date: string) {
  selectedAppointmentDate.value = date;
  selectedAppointmentTime.value = ""; // 清空时间选择
  form.date = ""; // 清空最终的预约时间

  if (!date) {
    appointmentTimeSlots.value = [];
    return;
  }

  try {
    // 加载对应日期的可用时间段
    const response = await getTimeSlots(date);
    if (response.code === 1) {
      appointmentTimeSlots.value = response.data;
    } else {
      ElMessage.error(response.msg || "获取时间段失败");
      appointmentTimeSlots.value = [];
    }
  } catch (error) {
    console.error("获取时间段失败:", error);
    ElMessage.error("获取时间段失败");
    appointmentTimeSlots.value = [];
  }
}

/** 预约时间选择变化 */
function onAppointmentTimeChange(time: string) {
  selectedAppointmentTime.value = time;
  form.date = time; // 设置最终的预约时间
}

/** 格式化日期显示 */
function formatDateDisplay(dateStr: string): string {
  try {
    const date = new Date(dateStr);
    const month = String(date.getMonth() + 1).padStart(2, "0");
    const day = String(date.getDate()).padStart(2, "0");
    return `${month}-${day}`;
  } catch (error) {
    return dateStr;
  }
}

/** 格式化时间显示 */
function formatTimeDisplay(dateTimeStr: string): string {
  try {
    const date = new Date(dateTimeStr);
    const hours = String(date.getHours()).padStart(2, "0");
    const minutes = String(date.getMinutes()).padStart(2, "0");
    return `${hours}:${minutes}`;
  } catch (error) {
    return dateTimeStr;
  }
}

/** 搜索会员 */
async function searchMembers(query: string) {
  if (!query) {
    filteredMemberList.value = memberList.value;
    return;
  }

  memberSearchLoading.value = true;
  try {
    const response = await getMemberList({
      keys: query,
      num: "50",
      page: "1"
    });
    if (response.code === 1) {
      filteredMemberList.value = response.data.list;
    } else {
      filteredMemberList.value = [];
    }
  } catch (error) {
    console.error("搜索会员失败:", error);
    filteredMemberList.value = [];
  } finally {
    memberSearchLoading.value = false;
  }
}

/** 会员选择变化 */
function onMemberChange(memberId: string) {
  const selectedMember = filteredMemberList.value.find(
    member => member.m_id === memberId
  );

  if (selectedMember) {
    form.name = selectedMember.m_name;
    form.mobile = selectedMember.m_mobile;
    form.mobile_val = selectedMember.mobile_val;
    form.mid = parseInt(selectedMember.m_id);
  } else {
    form.name = "";
    form.mobile = "";
    form.mid = undefined;
  }
}

/** 客户姓名变化 */
function onNameChange() {
  // 如果手动编辑了姓名，清除会员选择
  if (selectedMemberId.value) {
    selectedMemberId.value = "";
    form.mid = undefined;
  }
}

/** 联系电话变化 */
function onMobileChange(value) {
  console.log(value, "value");
  form.mobile = value;
  // 如果手动编辑了电话，清除会员选择
  if (selectedMemberId.value) {
    form.mobile_val = "";
    selectedMemberId.value = "";
    form.mid = undefined;
  }
}

/** 根据日期加载预约数据 */
async function loadOrdersByDate(date: string) {
  try {
    queryParams.start_date = date + " 00:00:00";
    queryParams.end_date = date + " 23:59:59";

    const response = await getOrderList(queryParams);
    if (response.code === 1) {
      orderList.value = response.data.list;
      updateCalendarData();
    }
  } catch (error) {
    console.error("获取预约数据失败:", error);
  }
}

/** 根据状态获取颜色 */
function getStatusColor(status: string): string {
  switch (status) {
    case "1": // 未到店
      return "#909399"; // 蓝色
    case "2": // 已到店
      return "#67C23A"; // 绿色
    case "3": // 已超时
      return "#F56C6C"; // 红色
    case "4": // 已取消
      return "#909399"; // 灰色
    case "5": // 服务已结束
      return "#F56C6C"; // 红色
    default:
      return "#fe6976"; // 默认粉色
  }
}

/** 显示自定义 popover */
function showPopover(event: MouseEvent, extendedProps: any) {
  // 清除之前的定时器
  if (popoverTimer.value) {
    clearTimeout(popoverTimer.value);
    popoverTimer.value = null;
  }

  currentEventData.value = extendedProps;
  updatePopoverPosition(event);
  popoverVisible.value = true;
}

/** 延迟隐藏 popover */
function hidePopoverWithDelay() {
  popoverTimer.value = setTimeout(() => {
    popoverVisible.value = false;
    currentEventData.value = null;
  }, 300); // 300ms 延迟
}

/** 鼠标进入 popover */
function handlePopoverMouseEnter() {
  if (popoverTimer.value) {
    clearTimeout(popoverTimer.value);
    popoverTimer.value = null;
  }
}

/** 鼠标离开 popover */
function handlePopoverMouseLeave() {
  hidePopoverWithDelay();
}

/** 更新 popover 位置 */
function updatePopoverPosition(event: MouseEvent) {
  const offset = 15;
  const popoverWidth = 320; // 预估宽度
  const popoverHeight = 200; // 预估高度

  let x = event.clientX + offset;
  let y = event.clientY + offset;

  // 防止超出右边界
  if (x + popoverWidth > window.innerWidth) {
    x = event.clientX - popoverWidth - offset;
  }

  // 防止超出下边界
  if (y + popoverHeight > window.innerHeight) {
    y = event.clientY - popoverHeight - offset;
  }

  popoverPosition.x = Math.max(10, x);
  popoverPosition.y = Math.max(10, y);
}

/** 根据状态获取状态文本 */
function getStatusText(status: string): string {
  switch (status) {
    case "1":
      return "未到店";
    case "2":
      return "已到店";
    case "3":
      return "已超时";
    case "4":
      return "已取消";
    case "5":
      return "服务已结束";
    default:
      return "未知";
  }
}

/** 编辑预约 */
function handleEditAppointment() {
  if (!currentEventData.value) return;

  // 填充表单数据
  form.id = parseInt(currentEventData.value.orderId);
  form.name = currentEventData.value.customerName;
  form.mobile = currentEventData.value.customerMobile;
  form.mobile_val = currentEventData.value.customerMobileVal;
  form.tid = currentEventData.value.technicianId;
  form.remark = currentEventData.value.remark;

  // 从原始数据获取上钟类型
  const order = orderList.value.find(
    o => o.l_id === currentEventData.value.orderId
  );
  if (order && order.l_type) {
    form.type = order.l_type;
  }

  // 根据客户姓名和手机号查找对应的会员
  const member = memberList.value.find(
    m =>
      m.m_name === currentEventData.value.customerName &&
      m.m_mobile === currentEventData.value.customerMobile
  );
  if (member) {
    selectedMemberId.value = member.m_id;
    form.mid = parseInt(member.m_id);
  }

  // 根据项目名称找到项目ID
  const project = projectList.value.find(
    p => p.p_name === currentEventData.value.projectName
  );
  if (project) {
    form.pid = project.p_id;
  }
  if (order) {
    form.date = order.yydate;

    // 解析日期和时间，填充到新的选择字段
    if (order.yydate) {
      const dateTime = new Date(order.yydate);
      const dateStr = dateTime.toISOString().split("T")[0];
      selectedAppointmentDate.value = dateStr;
      selectedAppointmentTime.value = order.yydate; // 使用完整的日期时间字符串

      console.log("编辑预约时间:", order.yydate);

      // 加载对应日期的时间段
      onAppointmentDateChange(dateStr);
      onAppointmentTimeChange(order.yydate); // 传递完整的日期时间字符串
    }
  }

  title.value = "编辑预约";
  eventClickFlag.value = false; // 设置为可编辑模式
  isEditMode.value = true; // 设置为编辑模式
  isEditOccupationMode.value = false; // 重置编辑占用模式
  activeTab.value = "appointment"; // 编辑时切换到预约标签页
  dialogVisible.value = true;

  // 隐藏 popover
  popoverVisible.value = false;
}

/** 编辑占用 */
function handleEditOccupation() {
  if (!currentEventData.value) return;

  // 从订单列表中找到对应的占用数据
  const occupation = orderList.value.find(
    o => o.l_id === currentEventData.value.orderId
  );

  if (occupation) {
    // 填充占用表单数据
    occupationForm.tid = occupation.l_jmid || occupation.l_tid;
    occupationForm.remark = occupation.l_remark;

    // 处理日期和时间
    const startTime = new Date(occupation.l_stime * 1000);
    const endTime = new Date(occupation.l_etime * 1000);

    occupationForm.date = startTime.toISOString().split("T")[0]; // YYYY-MM-DD
    occupationForm.startTime = startTime.toTimeString().substring(0, 5); // HH:mm
    occupationForm.endTime = endTime.toTimeString().substring(0, 5); // HH:mm

    // 保存占用ID用于编辑
    occupationForm.id = parseInt(currentEventData.value.orderId);
  }

  title.value = "编辑占用";
  eventClickFlag.value = false;
  isEditMode.value = false;
  isEditOccupationMode.value = true; // 设置为编辑占用模式
  activeTab.value = "occupation"; // 切换到占用标签页
  dialogVisible.value = true;

  // 隐藏 popover
  popoverVisible.value = false;
}

/** 取消占用 */
async function handleCancelOccupation() {
  if (!currentEventData.value) return;

  // 保存当前事件数据，防止在对话框过程中变为null
  const eventData = currentEventData.value;

  try {
    await ElMessageBox.confirm("确定要取消这个临时占用吗？", "取消占用", {
      confirmButtonText: "确定取消",
      cancelButtonText: "取消",
      type: "warning"
    });

    const response = await cancelOccupation(parseInt(eventData.orderId));

    if (response.code === 1) {
      ElMessage.success("取消占用成功");
      await loadOrders(); // 刷新数据
    } else {
      ElMessage.error(response.msg || "取消占用失败");
    }
  } catch (error) {
    if (error !== "cancel") {
      console.error("取消占用失败:", error);
      ElMessage.error("取消占用失败");
    }
  }

  // 隐藏 popover
  popoverVisible.value = false;
}

/** 确认到店 */
async function handleConfirmArrival() {
  if (!currentEventData.value) return;

  try {
    const response = await confirmArrival({
      id: currentEventData.value.orderId
    });
    if (response.code === 1) {
      ElMessage.success("确认到店成功");
      await loadOrders(); // 刷新数据
    } else {
      ElMessage.error(response.msg || "确认到店失败");
    }
  } catch (error) {
    console.error("确认到店失败:", error);
    ElMessage.error("确认到店失败");
  }

  // 隐藏 popover
  popoverVisible.value = false;
}

/** 取消预约 */
async function handleCancelOrder() {
  if (!currentEventData.value) return;

  // 保存当前事件数据，防止在对话框过程中变为null
  const eventData = currentEventData.value;

  try {
    const { value: cancelRemark } = await ElMessageBox.prompt(
      `确定要取消 ${eventData.customerName} 的预约吗？请输入取消原因：`,
      "取消预约",
      {
        confirmButtonText: "确定取消",
        cancelButtonText: "取消",
        type: "warning",
        inputPlaceholder: "请输入取消原因...",
        inputValidator: value => {
          if (!value || value.trim() === "") {
            return "请输入取消原因";
          }
          return true;
        },
        inputErrorMessage: "取消原因不能为空"
      }
    );

    const response = await cancelOrder({
      id: eventData.orderId,
      remark: cancelRemark.trim()
    });

    if (response.code === 1) {
      ElMessage.success("取消预约成功");
      await loadOrders(); // 刷新数据
    } else {
      ElMessage.error(response.msg || "取消预约失败");
    }
  } catch (error) {
    if (error !== "cancel") {
      console.error("取消预约失败:", error);
      ElMessage.error("取消预约失败");
    }
  }

  // 隐藏 popover
  popoverVisible.value = false;
}

/** 开始上钟 */
async function handleStartClock() {
  if (!currentEventData.value) return;

  try {
    const response = await startClock({
      id: currentEventData.value.orderId
    });
    if (response.code === 1) {
      ElMessage.success("开始上钟成功");
      await loadOrders(); // 刷新数据
    } else {
      ElMessage.error(response.msg || "开始上钟失败");
    }
  } catch (error) {
    console.error("开始上钟失败:", error);
    ElMessage.error("开始上钟失败");
  }

  // 隐藏 popover
  popoverVisible.value = false;
}

/** 确认已上钟 */
async function handleConfirmClock() {
  if (!currentEventData.value) return;

  try {
    const response = await confirmClock({
      id: currentEventData.value.orderId
    });
    if (response.code === 1) {
      ElMessage.success("确认已上钟成功");
      await loadOrders(); // 刷新数据
    } else {
      ElMessage.error(response.msg || "确认已上钟失败");
    }
  } catch (error) {
    console.error("确认已上钟失败:", error);
    ElMessage.error("确认已上钟失败");
  }

  // 隐藏 popover
  popoverVisible.value = false;
}

/** 确认支付 */
async function handleConfirmPayment() {
  if (!currentEventData.value) return;

  // 保存当前事件数据，防止在对话框过程中变为null
  const eventData = currentEventData.value;

  try {
    ElMessageBox.prompt("", "请输入实付金额", {
      confirmButtonText: "确定",
      cancelButtonText: "取消",
      type: "warning",
      inputPlaceholder: "请输入实付金额...",
      inputValidator: value => {
        if (!value || value.trim() === "" || isNaN(Number(value))) {
          return "请输入正确的实付金额";
        }
        return true;
      },
      inputErrorMessage: "请输入正确的实付金额"
    })
      .then(async ({ value }) => {
        const response = await confirmPayment({
          id: eventData.orderId,
          amount: value
        });

        if (response.code === 1) {
          ElMessage.success("确认支付成功");
          await loadOrders(); // 刷新数据
        } else {
          ElMessage.error(response.msg || "确认支付失败");
        }
      })
      .catch(() => {});
  } catch (error) {
    if (error !== "cancel") {
      console.error("确认支付失败:", error);
      ElMessage.error("确认支付失败");
    }
  }

  // 隐藏 popover
  popoverVisible.value = false;
}

/** 禁用过去的日期 */
function disabledDate(time: Date): boolean {
  const today = new Date();
  today.setHours(0, 0, 0, 0);
  return time.getTime() < today.getTime();
}

/** 禁用过去的时间 */
function disabledTime(date: Date): object {
  const now = new Date();
  const selectedDate = new Date(date);

  // 如果选择的是今天，则禁用当前时间之前的时间
  if (selectedDate.toDateString() === now.toDateString()) {
    return {
      disabledHours: () => {
        const hours = [];
        for (let i = 0; i < now.getHours(); i++) {
          hours.push(i);
        }
        return hours;
      },
      disabledMinutes: (hour: number) => {
        if (hour === now.getHours()) {
          const minutes = [];
          for (let i = 0; i <= now.getMinutes(); i++) {
            minutes.push(i);
          }
          return minutes;
        }
        return [];
      }
    };
  }

  return {};
}

/** 检查选择的时间是否有效 */
function isValidTime(selectedTime: string): boolean {
  const now = new Date();
  const selected = new Date(selectedTime);
  return selected.getTime() > now.getTime();
}

/** 选择技师和时间 */
function handleSelect(info: any) {
  const selectedTime = handleSelectDate(info.startStr);

  // 检查选择的时间是否在当前时间之前
  if (!isValidTime(selectedTime)) {
    ElMessage.warning("不能预约当前时间之前的时间段");
    return;
  }

  resetForm();
  resetOccupationForm();

  // 填充预约表单
  form.date = selectedTime;
  if (info.resource) {
    form.tid = info.resource.id;
    // 注意：这里不自动设置上钟类型，让用户手动选择
  }

  // 填充新的时间选择字段
  const selectedDate = selectedTime.split(" ")[0];
  selectedAppointmentDate.value = selectedDate;
  selectedAppointmentTime.value = selectedTime;

  // 加载对应日期的时间段
  onAppointmentDateChange(selectedDate);

  // 填充临时占用表单
  const selectedTimeOnly = selectedTime.split(" ")[1].substring(0, 5);
  occupationForm.date = selectedDate;
  occupationForm.startTime = selectedTimeOnly;
  if (info.resource) {
    occupationForm.tid = info.resource.id;
  }

  eventClickFlag.value = false;
  isEditMode.value = false; // 重置编辑模式
  isEditOccupationMode.value = false; // 重置编辑占用模式
  title.value = "新增预约";
  activeTab.value = "appointment";
  dialogVisible.value = true;
}

/** 处理选择的日期格式 */
function handleSelectDate(selectData: string): string {
  const originalTime = selectData;
  const date = new Date(originalTime);
  const year = date.getFullYear();
  const month = String(date.getMonth() + 1).padStart(2, "0");
  const day = String(date.getDate()).padStart(2, "0");
  const hours = String(date.getHours()).padStart(2, "0");
  const minutes = String(date.getMinutes()).padStart(2, "0");
  const formattedTime = `${year}-${month}-${day} ${hours}:${minutes}:00`;
  return formattedTime;
}

/** 重置表单 */
function resetForm() {
  form.id = undefined;
  form.mid = undefined;
  form.name = "";
  form.mobile = "";
  form.date = "";
  form.tid = "";
  form.type = "";
  form.pid = "";
  form.remark = "";

  // 重置预约时间选择相关字段
  selectedAppointmentDate.value = "";
  selectedAppointmentTime.value = "";
  appointmentTimeSlots.value = [];

  // 重置会员选择相关字段
  selectedMemberId.value = "";
  memberSearchKeyword.value = "";
  filteredMemberList.value = memberList.value;
}

/** 重置临时占用表单 */
function resetOccupationForm() {
  occupationForm.id = undefined;
  occupationForm.tid = "";
  occupationForm.date = "";
  occupationForm.startTime = "";
  occupationForm.endTime = "";
  occupationForm.remark = "";
}

/** 获取视图的日期参数 */
function getViewDate() {
  if (!calendar.value) return;

  const currentDate = calendar.value.getDate();
  const currentViewType = calendar.value.view.type;

  if (
    currentViewType === "resourceTimeGridDay" ||
    currentViewType === "resourceTimelineDay"
  ) {
    // 日视图
    const dateStr = formatDate(currentDate, "yyyy-MM-dd");
    queryParams.start_date = dateStr + " 00:00:00";
    queryParams.end_date = dateStr + " 23:59:59";
  } else if (
    currentViewType === "resourceTimeGridWeek" ||
    currentViewType === "resourceTimelineWeek"
  ) {
    // 周视图
    const startOfWeek = new Date(currentDate);
    startOfWeek.setDate(startOfWeek.getDate() - startOfWeek.getDay() + 1);
    const endOfWeek = new Date(startOfWeek);
    endOfWeek.setDate(endOfWeek.getDate() + 6);
    queryParams.start_date =
      formatDate(startOfWeek, "yyyy-MM-dd") + " 00:00:00";
    queryParams.end_date = formatDate(endOfWeek, "yyyy-MM-dd") + " 23:59:59";
  } else if (currentViewType === "dayGridMonth") {
    // 月视图
    const startOfMonth = new Date(currentDate);
    startOfMonth.setDate(1);
    const endOfMonth = new Date(currentDate);
    endOfMonth.setMonth(endOfMonth.getMonth() + 1);
    endOfMonth.setDate(0);
    queryParams.start_date =
      formatDate(startOfMonth, "yyyy-MM-dd") + " 00:00:00";
    queryParams.end_date = formatDate(endOfMonth, "yyyy-MM-dd") + " 23:59:59";
  }
}

/** 辅助方法：格式化日期 */
function formatDate(date: Date, format: string): string {
  const pad = (n: number) => (n < 10 ? "0" + n : n);
  return format
    .replace("yyyy", date.getFullYear().toString())
    .replace("MM", pad(date.getMonth() + 1))
    .replace("dd", pad(date.getDate()));
}

/** 上一个按钮事件 */
function prev() {
  calendar.value?.prev();
  getViewDate();
  loadOrders();
}

/** 切换下一个按钮事件 */
function next() {
  calendar.value?.next();
  getViewDate();
  loadOrders();
}

/** 点击今天按钮 */
function today() {
  calendar.value?.today();
  getViewDate();
  loadOrders();
}

/** 处理日期点击事件 */
function handleDateClick(arg: any) {
  console.log(arg, "日期点击事件");
}

/** 处理事件点击 */
function handleEventClick(calEvent: any) {
  console.log(calEvent, "事件点击");
  title.value = "查看预约详情";

  const extendedProps = calEvent.event.extendedProps;

  // 填充表单数据
  form.id = parseInt(extendedProps.orderId);
  form.name = extendedProps.customerName;
  form.mobile = extendedProps.customerMobile;
  form.mobile_val = extendedProps.customerMobileVal;
  form.date = calEvent.event.startStr;
  form.tid = extendedProps.technicianId;
  form.remark = extendedProps.remark;

  console.log("表单数据", form);

  // 从原始数据获取上钟类型
  const order = orderList.value.find(o => o.l_id === extendedProps.orderId);
  if (order && order.l_type) {
    form.type = order.l_type;
  }

  // 根据客户姓名和手机号查找对应的会员
  const member = memberList.value.find(
    m =>
      m.m_name === extendedProps.customerName &&
      m.m_mobile === extendedProps.customerMobile
  );
  if (member) {
    selectedMemberId.value = member.m_id;
    form.mid = parseInt(member.m_id);
  }

  // 填充新的时间选择字段
  if (calEvent.event.startStr) {
    const dateTime = new Date(calEvent.event.startStr);
    const dateStr = dateTime.toISOString().split("T")[0];
    selectedAppointmentDate.value = dateStr;
    selectedAppointmentTime.value = calEvent.event.startStr;
  }

  // 根据项目名称找到项目ID
  const project = projectList.value.find(
    p => p.p_name === extendedProps.projectName
  );
  if (project) {
    form.pid = project.p_id;
  }

  eventClickFlag.value = true;
  isEditMode.value = false; // 查看详情时不是编辑模式，但也不显示临时占用
  activeTab.value = "appointment"; // 查看详情时切换到预约标签页
  dialogVisible.value = true;
}

/** UTC时间去掉T */
function formmatTime(time: any): string {
  const utcTimestamp = time;
  const date = new Date(utcTimestamp);

  const year = date.getUTCFullYear();
  const month = String(date.getUTCMonth() + 1).padStart(2, "0");
  const day = String(date.getUTCDate()).padStart(2, "0");

  const hours = String(date.getUTCHours()).padStart(2, "0");
  const minutes = String(date.getUTCMinutes()).padStart(2, "0");
  const seconds = String(date.getUTCSeconds()).padStart(2, "0");

  const formattedDateTime = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;

  return formattedDateTime;
}

/** 日期设置回调 */
async function datesSet(info: any) {
  // 注意：该方法在页面初始化时就会触发一次
  const previousViewType = viewType.value;
  viewType.value = info.view.type;

  // 如果视图类型发生变化，重新加载数据
  if (previousViewType !== info.view.type && calendar.value) {
    console.log(`视图切换: ${previousViewType} -> ${info.view.type}`);

    // 立即清空所有事件，防止重复显示
    calendar.value.removeAllEvents();

    // 稍微延迟一下，确保视图切换完成
    await new Promise(resolve => setTimeout(resolve, 100));

    getViewDate();
    await loadOrders();
  }
}

/** 验证预约表单 */
function validateAppointmentForm(): boolean {
  // 验证预约日期
  if (!selectedAppointmentDate.value) {
    ElMessage.error("请选择预约日期");
    return false;
  }

  // 验证预约时间
  if (!selectedAppointmentTime.value) {
    ElMessage.error("请选择预约时间");
    return false;
  }

  return true;
}

/** 提交表单 */
async function submitForm() {
  try {
    // 先验证自定义字段
    if (!validateAppointmentForm()) {
      return;
    }

    await formRef.value?.validate();
    buttonLoading.value = true;

    const params: OrderActionParams = {
      name: form.name,
      mobile: form.mobile,
      date: form.date,
      tid: form.tid,
      pid: form.pid,
      remark: form.remark
    };

    // 只有在选择了技师时才传递上钟类型
    if (form.tid && form.type) {
      params.type = form.type;
    }

    // 如果选择了会员，传递mid；如果手动编辑了姓名或电话，不传mid或传mid=0
    if (selectedMemberId.value && form.mid) {
      params.mid = form.mid;
    } else {
      // 手动编辑的情况，不传mid或传0，让后端根据姓名和电话查找或创建
      params.mid = 0;
    }

    // 如果是编辑模式，添加id
    if (form.id) {
      params.id = form.id;
    }

    const response = await orderAction(params);
    if (response.code === 1) {
      ElMessage.success(response.msg || "操作成功");
      dialogVisible.value = false;
      // 刷新数据
      await loadOrders();
    } else {
      ElMessage.error(response.msg || "操作失败");
    }
  } catch (error) {
    console.error("提交失败:", error);
    ElMessage.error("提交失败");
  } finally {
    buttonLoading.value = false;
  }
}

/** 提交临时占用表单 */
async function submitOccupationForm() {
  try {
    await occupationFormRef.value?.validate();
    occupationButtonLoading.value = true;

    // 构造开始和结束时间
    const startDateTime = `${occupationForm.date} ${occupationForm.startTime}:00`;
    const endDateTime = `${occupationForm.date} ${occupationForm.endTime}:00`;

    let response;

    if (isEditOccupationMode.value && occupationForm.id) {
      // 编辑占用
      const params: EditOccupationParams = {
        id: occupationForm.id,
        tid: parseInt(occupationForm.tid),
        sdate: startDateTime,
        edate: endDateTime,
        remark: occupationForm.remark
      };
      response = await editOccupation(params);
    } else {
      // 新增占用
      const params: AddOccupationParams = {
        tid: parseInt(occupationForm.tid),
        sdate: startDateTime,
        edate: endDateTime,
        remark: occupationForm.remark
      };
      response = await addOccupation(params);
    }

    if (response.code === 1) {
      ElMessage.success(
        response.msg || (isEditOccupationMode.value ? "编辑成功" : "添加成功")
      );
      dialogVisible.value = false;
      resetOccupationForm();
      isEditOccupationMode.value = false; // 重置编辑模式
      // 刷新日历数据
      await loadOrders();
    } else {
      ElMessage.error(
        response.msg || (isEditOccupationMode.value ? "编辑失败" : "添加失败")
      );
    }
  } catch (error) {
    console.error("提交临时占用失败:", error);
    ElMessage.error("提交失败");
  } finally {
    occupationButtonLoading.value = false;
  }
}

/** 更新日历选择约束 */
function updateCalendarConstraints() {
  if (calendar.value) {
    // 更新日历配置以反映当前时间
    calendar.value.setOption("selectAllow", (selectInfo: any) => {
      const now = new Date();
      const selectedStart = new Date(selectInfo.start);
      return selectedStart.getTime() > now.getTime();
    });
  }
}

/** 刷新日历 */
async function refreshCalendar() {
  initCalendar();
  await loadOrders();
  updateCalendarConstraints();
  ElMessage.success("刷新成功");
}

/**
 * 取消按钮显示逻辑
 */

function isCancelBtn(timestamp) {
  // 将时间戳转换为毫秒（如果是秒级时间戳）
  const inputTime =
    timestamp.length === 10
      ? new Date(parseInt(timestamp) * 1000)
      : new Date(parseInt(timestamp));

  // 获取当前时间
  const now = new Date();

  // 获取当天的开始时间（00:00:00）
  const todayStart = new Date(now.getFullYear(), now.getMonth(), now.getDate());

  // 获取当天的结束时间（23:59:59.999）
  const todayEnd = new Date(
    now.getFullYear(),
    now.getMonth(),
    now.getDate() + 1
  );

  // 判断输入时间是否在今天的范围内
  if (inputTime >= todayStart && inputTime < todayEnd) {
    return true;
  } else {
    return ["1", "2"].includes(currentEventData.value.status);
  }
}

// 生命周期钩子
onMounted(async () => {
  // 等待DOM渲染完成后初始化日历
  await nextTick();
  initCalendar();
  // 初始化数据
  await initData();
  // 更新日历约束
  updateCalendarConstraints();

  // 设置陪班人员5分钟定时更新
  if (!dutyPersonTimer.value) {
    dutyPersonTimer.value = setInterval(
      () => {
        loadDutyPerson();
      },
      5 * 60 * 1000
    ); // 5分钟 = 300000毫秒
  }
});

onUnmounted(() => {
  // 清理资源
  calendar.value?.destroy();

  // 清理 popover 定时器
  if (popoverTimer.value) {
    clearTimeout(popoverTimer.value);
    popoverTimer.value = null;
  }

  // 清理陪班人员定时器
  if (dutyPersonTimer.value) {
    clearInterval(dutyPersonTimer.value);
    dutyPersonTimer.value = null;
  }
});
</script>
<style scoped lang="scss">
.app-container {
  padding: 5px;
}

.date-selector {
  margin-top: 16px;
}

.calendar-container {
  //margin-top: 16px;
  padding: 16px;
  min-height: 600px;
}

.tips-text {
  color: #666;
  font-size: 14px;
  margin-top: 8px;
}

:deep(.el-select) {
  width: 100%;
}

:deep(.el-date-editor.el-input),
:deep(.el-date-editor.el-input__inner) {
  width: 100%;
}

:deep(.fc) {
  width: 100% !important;
  height: auto;
  font-size: 0.875rem;
}

:deep(.fc-header-toolbar) {
  margin-bottom: 1rem;
}

:deep(.fc-event) {
  font-size: 11px;
  //height: 4rem;
  border-radius: 0;
  cursor: pointer;
  transition: all 0.2s ease;
}

:deep(.fc-event:hover) {
  transform: translateY(-2px);
  box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
  z-index: 10;
  filter: brightness(1.1);
}

:deep(.fc-event-title) {
  font-weight: 500;
  white-space: pre-line;
  word-break: break-word;
  text-align: center;
}

:deep(.fc-timegrid-event) {
  //min-height: 80px !important;
}

:deep(.fc-timeline-event) {
  min-height: 80px !important;
}

:deep(.fc-resource-timeline-divider) {
  width: 2px;
}

// resourceTimeGrid 垂直布局样式
:deep() {
  .fc-col-header-cell {
    text-align: center;
    font-weight: 600;
    background-color: #f8f9fa;
  }

  .fc-timegrid-col {
    border-right: 1px solid #dee2e6;
  }

  .fc-timegrid-slot {
    height: 1.7rem;
  }

  .fc-timegrid-slot-minor {
    border-bottom-style: dotted;
  }
}

// 响应式布局
@media (max-width: 768px) {
  :deep(.fc-header-toolbar) {
    flex-direction: column;
    gap: 0.75rem;
  }

  :deep(.fc-toolbar-chunk) {
    display: flex;
    justify-content: center;
  }

  :deep(.fc-event) {
    font-size: 10px;
  }

  // 移动端垂直布局优化
  :deep(.fc-resource-timegrid) {
    .fc-col-header-cell {
      font-size: 12px;
      padding: 8px 4px;
    }
  }
}

// 自定义日历按钮样式
:deep(.fc-addAppointment-button) {
  background-color: #409eff !important;
  border-color: #409eff !important;
  color: #ffffff !important;
  font-size: 12px !important;
  padding: 4px 12px !important;
  border-radius: 4px !important;
  margin-right: 8px !important;

  &:hover {
    background-color: #66b1ff !important;
    border-color: #66b1ff !important;
  }

  &:active {
    background-color: #3a8ee6 !important;
    border-color: #3a8ee6 !important;
  }
}

:deep(.fc-refresh-button) {
  background-color: #ffffff !important;
  border-color: #dcdfe6 !important;
  color: #606266 !important;
  font-size: 12px !important;
  padding: 4px 12px !important;
  border-radius: 4px !important;

  &:hover {
    background-color: #ecf5ff !important;
    border-color: #c6e2ff !important;
    color: #409eff !important;
  }

  &:active {
    background-color: #d9ecff !important;
    border-color: #a0cfff !important;
  }
}

:deep(.fc-event-main-frame) {
  flex-wrap: wrap;
}

// 自定义 Popover 样式
.custom-popover {
  position: fixed;
  z-index: 9999;
  background: #ffffff;
  color: #333;
  border-radius: 12px;
  box-shadow:
    0 12px 32px rgba(0, 0, 0, 0.12),
    0 2px 6px rgba(0, 0, 0, 0.08);
  font-size: 13px;
  max-width: 320px;
  min-width: 280px;
  pointer-events: auto;
  opacity: 0;
  animation: popoverFadeIn 0.2s ease-out forwards;
  border: 1px solid #e4e7ed;

  .popover-content {
    .popover-header {
      padding: 16px 16px 12px;
      border-bottom: 1px solid #f0f0f0;
      display: flex;
      justify-content: space-between;
      align-items: flex-start;

      .customer-info {
        flex: 1;

        .customer-name {
          display: block;
          font-weight: 600;
          font-size: 15px;
          color: #303133;
          margin-bottom: 4px;
        }

        .customer-mobile {
          display: block;
          font-size: 12px;
          color: #909399;
        }
      }

      .status-badge {
        padding: 4px 8px;
        border-radius: 12px;
        font-size: 11px;
        font-weight: 500;
        flex-shrink: 0;

        &.status-1 {
          background: #ecf5ff;
          color: #409eff;
          border: 1px solid #d9ecff;
        }

        &.status-2 {
          background: #f0f9ff;
          color: #67c23a;
          border: 1px solid #e1f3d8;
        }

        &.status-3 {
          background: #fef0f0;
          color: #f56c6c;
          border: 1px solid #fde2e2;
        }

        &.status-4 {
          background: #f4f4f5;
          color: #909399;
          border: 1px solid #e9e9eb;
        }

        &.status-5 {
          background: #fef0f0;
          color: #f56c6c;
          border: 1px solid #fde2e2;
        }
      }
    }

    .popover-body {
      padding: 12px 16px;

      .info-grid {
        display: grid;
        grid-template-columns: 1fr 1fr;
        gap: 8px;

        .info-item {
          display: flex;
          align-items: center;
          font-size: 12px;

          &.full-width {
            grid-column: 1 / -1;
          }

          i {
            width: 16px;
            height: 16px;
            margin-right: 6px;
            opacity: 0.7;
            flex-shrink: 0;

            &.icon-time::before {
              content: "🕐";
            }

            &.icon-user::before {
              content: "👤";
            }

            &.icon-service::before {
              content: "💆";
            }

            &.icon-price::before {
              content: "💰";
            }

            &.icon-duration::before {
              content: "⏳";
            }

            &.icon-note::before {
              content: "📝";
            }
          }

          span {
            color: #606266;
            line-height: 1.4;
            word-break: break-word;
            font-size: 12px;
          }
        }
      }
    }

    .popover-footer {
      padding: 8px 16px 16px;
      display: flex;
      gap: 8px;
      justify-content: flex-end;
      border-top: 1px solid #f0f0f0;

      .el-button {
        font-size: 12px;
        padding: 4px 12px;
        height: 28px;
      }
    }
  }
}

@keyframes popoverFadeIn {
  from {
    opacity: 0;
    transform: translateY(-8px) scale(0.95);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}
</style>
